package com.njlime.cms.util;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.njlime.cms.sdk.weibo4j.http.BASE64Encoder;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Hashtable;

/**
 * 生成二维码
 * Created by Dean on 2017-11-2.
 */
public class QRUtils {

    /**
     * 二维码图片的生成
     * @param content           链接
     * @param qrcode_width      二维码宽
     * @param qrcode_height     二维码高
     * @return
     * @throws Exception
     */
    public static BufferedImage createImage(String content, int qrcode_width, int qrcode_height) throws Exception {
        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        hints.put(EncodeHintType.MARGIN, 1);
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
                BarcodeFormat.QR_CODE, qrcode_width, qrcode_height, hints);
        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        BufferedImage image = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
            }
        }
        return image;
    }

    /**
     * Base64编码
     * @param content
     * @param qrcode_width
     * @param qrcode_height
     * @return
     */
    public static String qrCodeBase64(String content, int qrcode_width, int qrcode_height) {
        String imageString = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try{
            ImageIO.write(createImage(content, qrcode_width, qrcode_height), "jpg", bos);
            byte[] imageBytes = bos.toByteArray();
            BASE64Encoder encoder = new BASE64Encoder();
            imageString = encoder.encode(imageBytes);
            bos.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        return imageString;
    }

    /**
     * 下载
     * @param response
     * @param fileName
     * @param content
     * @param type
     */
    public static void downQrCode(HttpServletResponse response,String fileName, String content, int type){
        int width = 0,height = 0;
        if(type == 1){
            width = 500;
            height = 500;
        }else if(type == 2){
            width = 1500;
            height = 1500;
        }else if(type == 3){
            width = 3000;
            height = 3000;
        }
        downQrCode(response, fileName, content, width, height);
    }

    /**
     * 下载
     * @param response
     * @param fileName
     * @param content
     * @param qrcode_width
     * @param qrcode_height
     */
    public static void downQrCode(HttpServletResponse response,String fileName, String content, int qrcode_width, int qrcode_height){
        try{
            response.reset();
            response.setContentType("application/x-msdownload");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ImageOutputStream imageOutput = ImageIO.createImageOutputStream(byteArrayOutputStream);
            ImageIO.write(createImage(content, qrcode_width, qrcode_height), "jpg", imageOutput);
            InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());

            byte[] bytes = new byte[1024];
            OutputStream outputStream = response.getOutputStream();
            long count = 0;
            while(count < imageOutput.length()){
                int len = inputStream.read(bytes, 0, 1024);
                count +=len;
                outputStream.write(bytes, 0, len);
            }
            outputStream.flush();
            outputStream.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }


}
